/**
 * 检查Node.js版本并尝试使用nvm切换到正确版本
 * 增强版错误处理 - Windows nvm优化版
 */

const requiredVersion = '20.19.1';

// 颜色输出函数
const colors = {
  red: text => `\x1b[31m${text}\x1b[0m`,
  green: text => `\x1b[32m${text}\x1b[0m`,
  yellow: text => `\x1b[33m${text}\x1b[0m`,
  cyan: text => `\x1b[36m${text}\x1b[0m`,
  bold: text => `\x1b[1m${text}\x1b[0m`,
};

// 安全的命令执行函数
function safeExecSync(command, options = {}) {
  try {
    const { execSync } = require('child_process');
    return execSync(command, {
      stdio: 'pipe',
      encoding: 'utf8',
      timeout: 10000, // 10秒超时
      ...options,
    });
  } catch (error) {
    return null;
  }
}

// 检查Node.js版本
function checkNodeVersion() {
  try {
    const currentVersion = process.version.slice(1); // 移除版本号前的'v'

    if (currentVersion === requiredVersion) {
      console.log(colors.green(`✓ Node.js版本检查通过: ${currentVersion}`));
      return true;
    }

    console.log(colors.yellow(`⚠ Node.js版本不匹配:`));
    console.log(`  当前版本: ${colors.red(currentVersion)}`);
    console.log(`  要求版本: ${colors.green(requiredVersion)}`);

    return false;
  } catch (error) {
    console.error(colors.red(`✗ 无法获取Node.js版本信息: ${error.message}`));
    process.exit(1);
  }
}

// 检测nvm是否安装
function detectNvm() {
  console.log(colors.cyan('正在检测nvm安装状态...'));

  // Windows nvm检测
  if (process.platform === 'win32') {
    // 检查nvm是否在PATH中
    const nvmPath = safeExecSync('where nvm');
    if (nvmPath) {
      console.log(colors.green(`✓ 检测到Windows nvm路径: ${nvmPath.trim()}`));
      return 'windows';
    }

    // 检查常见的nvm安装路径
    const commonPaths = [
      'C:\\Program Files\\nodejs\\nvm.exe',
      'C:\\Program Files (x86)\\nodejs\\nvm.exe',
      process.env.NVM_HOME ? `${process.env.NVM_HOME}\\nvm.exe` : null,
      process.env.APPDATA ? `${process.env.APPDATA}\\nvm\\nvm.exe` : null,
    ].filter(Boolean);

    for (const path of commonPaths) {
      try {
        const fs = require('fs');
        if (fs.existsSync(path)) {
          console.log(colors.green(`✓ 检测到Windows nvm: ${path}`));
          return 'windows';
        }
      } catch (e) {
        // 忽略文件系统错误
      }
    }

    // 检查环境变量
    if (process.env.NVM_HOME || process.env.NVM_SYMLINK) {
      console.log(colors.green(`✓ 检测到nvm环境变量`));
      return 'windows';
    }
  } else {
    // Unix系统nvm检测
    const nvmVersion = safeExecSync(
      '. ~/.nvm/nvm.sh && nvm --version 2>/dev/null',
      { shell: '/bin/bash' }
    );
    if (nvmVersion) {
      console.log(colors.green(`✓ 检测到Unix nvm: ${nvmVersion.trim()}`));
      return 'unix';
    }

    // 检查其他可能的nvm安装路径
    const altNvmVersion = safeExecSync(
      'source ~/.bashrc && nvm --version 2>/dev/null',
      { shell: '/bin/bash' }
    );
    if (altNvmVersion) {
      console.log(
        colors.green(`✓ 检测到Unix nvm (通过bashrc): ${altNvmVersion.trim()}`)
      );
      return 'unix-alt';
    }
  }

  console.log(colors.red('✗ 未检测到nvm安装'));
  return null;
}

// 检查指定版本的Node.js是否已安装 (仅Unix系统)
function checkNodeVersionInstalled(nvmType) {
  console.log(colors.cyan(`检查Node.js ${requiredVersion}是否已安装...`));

  let command;
  let options = {};

  switch (nvmType) {
    case 'unix':
      command = '. ~/.nvm/nvm.sh && nvm list';
      options.shell = '/bin/bash';
      break;
    case 'unix-alt':
      command = 'source ~/.bashrc && nvm list';
      options.shell = '/bin/bash';
      break;
    default:
      return false;
  }

  const result = safeExecSync(command, options);
  if (result && result.includes(requiredVersion)) {
    console.log(colors.green(`✓ Node.js ${requiredVersion}已安装`));
    return true;
  }

  console.log(colors.yellow(`⚠ Node.js ${requiredVersion}未安装`));
  return false;
}

// 安装指定版本的Node.js (仅Unix系统)
function installNodeVersion(nvmType) {
  console.log(colors.cyan(`正在安装Node.js ${requiredVersion}...`));

  let command;
  let options = {};

  switch (nvmType) {
    case 'unix':
      command = `. ~/.nvm/nvm.sh && nvm install ${requiredVersion}`;
      options.shell = '/bin/bash';
      break;
    case 'unix-alt':
      command = `source ~/.bashrc && nvm install ${requiredVersion}`;
      options.shell = '/bin/bash';
      break;
    default:
      return false;
  }

  try {
    const { execSync } = require('child_process');
    execSync(command, { stdio: 'inherit', timeout: 300000, ...options }); // 5分钟超时
    console.log(colors.green(`✓ Node.js ${requiredVersion}安装成功`));
    return true;
  } catch (error) {
    console.error(colors.red(`✗ Node.js ${requiredVersion}安装失败:`));
    console.error(colors.red(`  错误信息: ${error.message}`));
    return false;
  }
}

// 切换到指定版本的Node.js (仅Unix系统)
function switchNodeVersion(nvmType) {
  console.log(colors.cyan(`正在切换到Node.js ${requiredVersion}...`));

  let command;
  let options = {};

  switch (nvmType) {
    case 'unix':
      command = `. ~/.nvm/nvm.sh && nvm use ${requiredVersion}`;
      options.shell = '/bin/bash';
      break;
    case 'unix-alt':
      command = `source ~/.bashrc && nvm use ${requiredVersion}`;
      options.shell = '/bin/bash';
      break;
    default:
      return false;
  }

  try {
    const { execSync } = require('child_process');
    execSync(command, { stdio: 'inherit', timeout: 30000, ...options }); // 30秒超时
    console.log(colors.green(`✓ 成功切换到Node.js ${requiredVersion}`));
    return true;
  } catch (error) {
    console.error(colors.red(`✗ 切换Node.js版本失败:`));
    console.error(colors.red(`  错误信息: ${error.message}`));

    if (error.message.includes('not installed')) {
      console.log(
        colors.yellow(`  提示: Node.js ${requiredVersion}可能未安装`)
      );
    }

    return false;
  }
}

// 显示Windows手动解决方案
function showWindowsManualSolution() {
  console.log(colors.bold('\n📋 Windows nvm 手动操作指南:'));
  console.log(colors.cyan('\n由于Windows nvm的限制，需要您手动执行以下步骤:'));

  console.log(colors.yellow('\n1. 打开新的PowerShell或CMD窗口'));
  console.log(colors.yellow('2. 检查是否已安装目标版本:'));
  console.log(`   ${colors.green('nvm list')}`);

  console.log(colors.yellow('\n3. 如果未安装，请先安装:'));
  console.log(`   ${colors.green(`nvm install ${requiredVersion}`)}`);

  console.log(colors.yellow('\n4. 切换到目标版本:'));
  console.log(`   ${colors.green(`nvm use ${requiredVersion}`)}`);

  console.log(colors.yellow('\n5. 验证版本切换成功:'));
  console.log(`   ${colors.green('node --version')}`);

  console.log(colors.yellow('\n6. 重新运行您的项目命令'));

  console.log(
    colors.cyan('\n💡 提示: 如果遇到权限问题，请以管理员身份运行终端')
  );
  console.log(
    colors.cyan('💡 提示: 每次打开新终端都需要重新执行 nvm use 命令')
  );
}

// 显示通用手动解决方案
function showManualSolution() {
  console.log(colors.bold('\n📋 手动解决方案:'));

  if (process.platform === 'win32') {
    console.log(colors.cyan('Windows用户 (推荐使用nvm-windows):'));
    console.log(
      `  1. 如果未安装nvm-windows，请访问: ${colors.cyan('https://github.com/coreybutler/nvm-windows')}`
    );
    console.log(
      `  2. 在 ${colors.bold('PowerShell')} 或 ${colors.bold('CMD')} 中运行以下命令:`
    );
    console.log(`     ${colors.green(`nvm install ${requiredVersion}`)}`);
    console.log(`     ${colors.green(`nvm use ${requiredVersion}`)}`);
    console.log(`  3. 重新运行您的项目命令`);
    console.log(
      colors.yellow(
        '\n  ⚠ 注意: nvm命令必须在终端中手动执行，无法通过脚本自动运行'
      )
    );
  } else {
    console.log(colors.cyan('macOS/Linux用户:'));
    console.log(
      `  1. 如果未安装nvm，请访问: ${colors.cyan('https://github.com/nvm-sh/nvm')}`
    );
    console.log(
      `  2. 重新加载shell配置: ${colors.green('source ~/.bashrc')} 或 ${colors.green('source ~/.zshrc')}`
    );
    console.log(`  3. 运行: ${colors.green(`nvm install ${requiredVersion}`)}`);
    console.log(`  4. 运行: ${colors.green(`nvm use ${requiredVersion}`)}`);
  }

  console.log(colors.cyan('\n🌐 或者直接从官网下载安装Node.js:'));
  console.log(`  ${colors.cyan('https://nodejs.org/')}`);
  console.log(`  下载并安装 ${colors.green(`v${requiredVersion}`)} 版本`);
}

// 主函数
function main() {
  try {
    console.log(
      colors.bold(`\n🔍 Node.js版本检查器 (要求版本: ${requiredVersion})\n`)
    );

    // 检查当前Node.js版本
    if (checkNodeVersion()) {
      console.log(colors.green('\n✅ 版本检查通过，可以继续运行项目\n'));
      return;
    }

    // 检测nvm
    const nvmType = detectNvm();
    if (!nvmType) {
      console.log(colors.red('\n❌ 未检测到nvm，无法自动切换Node.js版本'));
      showManualSolution();
      process.exit(1);
    }

    // Windows nvm特殊处理 - 直接显示手动操作指南
    if (nvmType === 'windows') {
      showWindowsManualSolution();
      process.exit(1);
    }

    // Unix系统的自动处理流程
    console.log(colors.cyan('\n🚀 检测到Unix系统nvm，尝试自动处理...'));

    // 检查目标版本是否已安装
    const isInstalled = checkNodeVersionInstalled(nvmType);

    // 如果未安装，尝试安装
    if (!isInstalled) {
      console.log(
        colors.yellow(`\n⚠ 正在尝试安装Node.js ${requiredVersion}...`)
      );
      if (!installNodeVersion(nvmType)) {
        console.log(colors.red('\n❌ 自动安装失败'));
        showManualSolution();
        process.exit(1);
      }
    }

    // 尝试切换版本
    if (switchNodeVersion(nvmType)) {
      console.log(colors.green('\n✅ Node.js版本切换成功！'));
      console.log(colors.cyan('请重新运行您的命令。'));
    } else {
      console.log(colors.red('\n❌ 自动切换失败'));
      showManualSolution();
      process.exit(1);
    }
  } catch (error) {
    console.error(colors.red(`\n💥 脚本执行出现未预期的错误:`));
    console.error(colors.red(`错误类型: ${error.name}`));
    console.error(colors.red(`错误信息: ${error.message}`));

    if (error.stack) {
      console.error(colors.red(`错误堆栈:`));
      console.error(error.stack);
    }

    console.log(colors.yellow('\n请尝试手动解决:'));
    showManualSolution();
    process.exit(1);
  }
}

// 运行主函数
main();
